package com.eis.sap.in.connector;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import com.eis.sap.in.connector.bean.ParameterContainer;
import com.eis.sap.in.connector.conf.SapConnParameter;
import com.eis.sap.in.connector.bean.FunctionImportingParameter;
import com.eis.thirdsys.connector.conf.ConnectorConfig;
import com.sap.mw.jco.IFunctionTemplate;
import com.sap.mw.jco.JCO;
import com.sap.mw.jco.JCO.ParameterList;

public class ConnectorBase extends Object {
	protected JCO.Client mConnection = null;
	protected JCO.Repository mRepository;
	protected ConnectorConfig connectorConfig;

	public ConnectorBase() {
		super();
	}

	public void dispose() {
		if (mConnection != null && mConnection.isAlive()) {
			mConnection.disconnect();
		}
	}

	protected void connect(ConnectorConfig connectorConfig) {
		this.connectorConfig = connectorConfig;
			// Create a client connection to a dedicated R/3 system
			// This should be put into DB as config.
			// It will be a RFC uses of the corresponding SAP System.
			mConnection = JCO
					.createClient(
							connectorConfig.getOneConf(
									SapConnParameter.client.name())
									.getValue(), // SAP client
							connectorConfig.getOneConf(
									SapConnParameter.uid.name())
									.getValue(), // userid
							connectorConfig.getOneConf(
									SapConnParameter.password.name())
									.getValue(), // password
							connectorConfig.getOneConf(
									SapConnParameter.language.name())
									.getValue(), // language
							connectorConfig.getOneConf(
									SapConnParameter.systemAddress.name())
									.getValue(), // ,"amtcloud06.isipl.com" //
													// host name
							connectorConfig.getOneConf(
									SapConnParameter.instanceNo.name())
									.getValue()); // instance No
			// Open the connection
			mConnection.connect();
			mRepository = new JCO.Repository("EISTech", mConnection);
	}

	protected JCO.Function createFunction(String name) {
		IFunctionTemplate ft = mRepository.getFunctionTemplate(name
					.toUpperCase());
		if (ft == null) return null;
		return ft.getFunction();
	}

	protected void ExecuteFunction(JCO.Function function) {
		this.mConnection.execute(function);
	}

	protected ParameterContainer GetImportingParameters(JCO.Function function) {
		ParameterContainer con = new ParameterContainer();
		con.ImportParameterList = function.getImportParameterList();
		return con;
	}

	protected ParameterContainer GetExportingParameters(JCO.Function function) {
		ParameterContainer con = new ParameterContainer();
		con.ExportParameterList = function.getExportParameterList();
		return con;
	}

	protected ParameterContainer GetTableParameters(JCO.Function function) {
		ParameterContainer con = new ParameterContainer();
		con.TableParameterList = function.getTableParameterList();
		return con;
	}

	/**
	 * 
	 * @param functionName
	 * @param parameters
	 * @param lastRuntime
	 * @param LastRunDate
	 * @return
	 * @throws Exception
	 */
	public ArrayList<HashMap<String, Object>> execute(String functionName,
			List<FunctionImportingParameter> parameters, String lastRuntime,
			String LastRunDate){
		JCO.Table data = null;
		ArrayList<HashMap<String, Object>> returnList = new ArrayList<HashMap<String, Object>>();
		
			JCO.Function function;
			
			function = this.createFunction(functionName);

			ParameterContainer paraContainer = this
					.GetImportingParameters(function);
			paraContainer.ImportParameterList.setValue(lastRuntime,
					"ID_LAST_RUN_TIME");
			paraContainer.ImportParameterList.setValue(LastRunDate,
					"ID_LAST_RUN_DATE");

			ParameterList importingPL = function.getImportParameterList();
			if (parameters != null) {
				for (FunctionImportingParameter parameter : parameters) {
					if (!parameter.isList()) {
						if (importingPL.hasField(parameter.getParameterName())) {
							paraContainer.ImportParameterList.setValue(
									parameter.getSingleParameterValue(),
									parameter.getParameterName());
						}
					} else {
						JCO.Table paraTable = function.getTableParameterList()
								.getTable(parameter.getParameterName());

						for (int i = 0; i < parameter.getListParameterValue().length; i++) {
							paraTable.appendRow();
							paraTable.setRow(i);
							paraTable.setValue(
									parameter.getListParameterValue()[i],
									"FIELD");
						}
					}
				}
			}

			mConnection.execute(function);

			data = function.getTableParameterList().getTable("ET_DATA");
			for (int i = 0; i < data.getNumRows(); i++) {
				data.setRow(i);
				HashMap<String, Object> map = new HashMap<String, Object>();
				for (int colNum = 0; colNum < data.getNumColumns(); colNum++) {
					String key = data.getName(colNum);
					map.put(key, data.getValue(key));
				}
				returnList.add(map);
			}

		
		return returnList;
	}
}
